package com.taobao.ucenter.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.taobao.base.model.RestResponse;
import com.taobao.ucenter.feignclient.MeClient;
import com.taobao.ucenter.mapper.UserAuthMapper;
import com.taobao.ucenter.mapper.UserRoleMapper;
import com.taobao.ucenter.mapper.WxUserMapper;
import com.taobao.ucenter.model.dto.AuthParamsDto;
import com.taobao.ucenter.model.dto.UserExt;
import com.taobao.ucenter.model.dto.Users;
import com.taobao.ucenter.model.po.UserAuth;
import com.taobao.ucenter.model.po.WxUser;
import com.taobao.ucenter.service.AuthService;
import com.taobao.ucenter.service.WxAuthService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * 微信扫码认证
 */
@Service("wx_authservice")
public class WxAuthServiceImpl implements AuthService, WxAuthService {

    @Autowired
    UserAuthMapper userAuthMapper;
    @Autowired
    WxUserMapper wxUserMapper;
    @Autowired
    MeClient meClient;
    @Autowired
    UserRoleMapper userRoleMapper;


    @Autowired
    RestTemplate restTemplate;


    @Value("${weixin.appid}")
    String appid;
    @Value("${weixin.secret}")
    String secret;
    @Value("${weixin.domain}")
    String domain;
    @Value("${weixin.redirect_uri}")
    String redirect_uri;


    @Override
    public String getWeChatQRCode() {

        String qrCode = "";
        /**
         * appid
         * redirect_uri 授权后重定向的回调链接地址
         * scope snsapi_userinfo
         * state 重定向后会带上state参数，开发者可以填写a-zA-Z0-9的参数值，最多128字节
         * #wechat_redirect	重定向后会带上#wechat_redirect，请开发者注意URL处理
         */
        String content = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
                "appid=" + appid +
                "&redirect_uri=" + redirect_uri +
                "&response_type=code" +
                "&scope=snsapi_userinfo" +
                "&state=777#wechat_redirect";
//        String content = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
//                "appid=your_appid&redirect_uri=your_redirect_uri" +
//                "&response_type=code&scope=snsapi_userinfo&state=777#wechat_redirect";
//        content = content.replace("your_appid", appid).replace("your_redirect_uri", redirect_uri);
        int width = 200;
        int height = 200;
        QrConfig qrConfig = new QrConfig(width, height);
        qrConfig.setImg(FileUtil.file("img/weixin_logo.png")); // 设置logo图片
        qrCode = QrCodeUtil.generateAsBase64(content, qrConfig, "png");

        return qrCode;
    }

    @Override
    public UserAuth wxAuth(String code) {
        //申请令牌
        Map<String, String> access_token_map = getAccess_token(code);
        //访问令牌
        String access_token = access_token_map.get("access_token");
        String openid = access_token_map.get("openid");

        //携带令牌查询用户信息
        Map<String, String> userinfo = getUserinfo(access_token, openid);

        // 保存用户信息到数据库
        UserAuth userAuth = this.addWxUser(userinfo);

        return userAuth;
    }


    /**
     * 携带授权码申请令牌
     * https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
     * <p>
     * {
     * "access_token":"ACCESS_TOKEN",
     * "expires_in":7200,
     * "refresh_token":"REFRESH_TOKEN",
     * "openid":"OPENID",
     * "scope":"SCOPE",
     * "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
     * }
     *
     * @param code 授权
     * @return
     */
    private Map<String, String> getAccess_token(String code) {

        String url_template = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
        //最终的请求路径
        String url = String.format(url_template, appid, secret, code);

        //远程调用此url
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, null, String.class);
        //获取响应的结果
        String result = exchange.getBody();
        //将result转成map
        Map<String, String> map = JSON.parseObject(result, Map.class);
        return map;
    }

    /**
     * 携带令牌查询用户信息
     * <p>
     * https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
     * <p>
     * {
     * "openid":"OPENID",
     * "nickname":"NICKNAME",
     * "sex":1,
     * "province":"PROVINCE",
     * "city":"CITY",
     * "country":"COUNTRY",
     * "headimgurl": "https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
     * "privilege":[
     * "PRIVILEGE1",
     * "PRIVILEGE2"
     * ],
     * "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
     * <p>
     * }
     */
    private Map<String, String> getUserinfo(String access_token, String openid) {

        String url_template = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s";
        String url = String.format(url_template, access_token, openid);

        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.GET, null, String.class);

        //获取响应的结果
        String result = new String(exchange.getBody().getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        //将result转成map
        Map<String, String> map = JSON.parseObject(result, Map.class);
        return map;

    }

    /**
     * 微信认证
     * 返回完整的用户信息
     */
    @Override
    public UserExt execute(AuthParamsDto authParamsDto) {
        //得到账号
        String username = authParamsDto.getUsername();
        //查询数据库  微信扫码的不用密码认证
        UserAuth userAuth = userAuthMapper.selectOne(new LambdaQueryWrapper<UserAuth>().eq(UserAuth::getUsername, username));
        if (userAuth == null) {
            throw new RuntimeException("用户不存在");
        }

        UserExt userExt = new UserExt();
        BeanUtils.copyProperties(userAuth, userExt);

        return userExt;
    }

    @Transactional
    public UserAuth addWxUser(Map<String, String> userInfo_map) {
        String openid = userInfo_map.get("openid");
        String nickname = userInfo_map.get("nickname");
        //根据openid查询用户信息
        UserAuth userAuth = userAuthMapper.selectOne(new LambdaQueryWrapper<UserAuth>().eq(UserAuth::getOpenid, openid));
        if (userAuth != null) {
            return userAuth;
        }
        //向数据库新增记录
        WxUser wxUser = new WxUser();
        wxUser.setCity(userInfo_map.get("city"));
        wxUser.setCountry(userInfo_map.get("country"));
        wxUser.setHeadimgurl(userInfo_map.get("headimgurl"));
        wxUser.setNickname(nickname);
        wxUser.setOpenid(openid);
        wxUser.setProvince(userInfo_map.get("province"));
        Object sex = userInfo_map.get("sex");
        wxUser.setSex(sex.equals("1") ? 1 : 0);
        wxUser.setCreateTime(LocalDateTime.now());
        this.wxUserMapper.insert(wxUser);

        userAuth = new UserAuth();
        userAuth.setOpenid(openid);
        userAuth.setCreateTime(LocalDateTime.now());
        userAuth.setPhone("");
        userAuth.setName(nickname);
        userAuth.setUsername(openid);
        //插入
        int insert = this.userAuthMapper.insert(userAuth);

        Users users = new Users();
        users.setUserId(userAuth.getUserId());
        users.setUsername(userAuth.getUsername());
        users.setCreateTime(LocalDateTime.now());
        users.setUpdateTime(LocalDateTime.now());
        users.setTbName(nickname);
        users.setHeadimgurl(wxUser.getHeadimgurl());
        users.setSex(wxUser.getSex() == 1 ? "1" : "0");
        users.setStatus("1");
        RestResponse<String> stringRestResponse = this.meClient.insertUser(users);

//
//        //向用户角色关系表新增记录
//        UserRole tbUserRole = new UserRole();
//        tbUserRole.setId(UUID.randomUUID().toString());
//        tbUserRole.setUserId(userId);
//        tbUserRole.setRoleId("17");//学生角色
//        tbUserRole.setCreateTime(LocalDateTime.now());
//        userRoleMapper.insert(tbUserRole);

        return userAuth;

    }

}
